﻿using System;
using ClusterAware;
using ClusterAwareProperties;
using ClusterAwareAdmin.Properties;
using System.Management;

namespace ClusterAwareAdmin
{
    /// <summary>
    /// Admin Resource Methods Class
    /// </summary>
    public class ResourceAdmin: ResourceMethods
    {

        #region private properties

        private readonly ClusterManagerAdmin _managerclass;

        #endregion

        #region CTOR

        /// <summary>
        /// Create Class ResourceAdmin
        /// </summary>
        /// <param name="managerclass">Instance of ClusterManager class</param>
        public ResourceAdmin(ClusterManagerAdmin managerclass)
            : base(managerclass.ManagerInstance)
        {
            _managerclass = managerclass;
        }

        #endregion

        #region public Methods

        ///<summary>
        /// Creates a resource.
        ///</summary>
        ///<param name="groupName">The name of the group to receive the resource.</param>
        ///<param name="resourceName">The name to assign to the resource.</param>
        ///<param name="resourceType">The type of resource to create.</param>
        ///<param name="separateMonitor">
        /// If false The resource does not need a separate resource monitor. 
        /// IF true The resource needs a separate resource monitor.
        /// </param>
        /// <remarks>
        /// If the group does not exist it is created.
        /// </remarks>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource Type not exist
        /// Failed WMI method execution
        /// </exception>
        public void Create(string groupName, string resourceName, string resourceType, bool separateMonitor)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(groupName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "groupName"));
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(resourceType))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceType"));
            }
            if (!_managerclass.ResourceTypes.ExistResourceType(resourceType))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "ResourceType", resourceType));
            }
            if (!_managerclass.Groups.ExistGroup(groupName))
            {
                _managerclass.Groups.Create(groupName);
            }
            try
            {
                var path = new ManagementPath("MSCluster_Resource");
                using (var classInstance = new ManagementClass(_managerclass.ScopeManager, path, new ObjectGetOptions()))
                {
                    using (var inParams = classInstance.GetMethodParameters("CreateResource"))
                    {
                        inParams["Group"] = groupName;
                        inParams["ResourceName"] = resourceName;
                        inParams["ResourceType"] = resourceType;
                        inParams["SeparateMonitor"] = separateMonitor;
                        classInstance.InvokeMethod("CreateResource", inParams, null);
                        if (_managerclass.CacheInstances)
                        {
                            _managerclass.Refresh(RefreshOption.Resources,resourceName);
                        }
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resource.Create", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resource.Create", ex.Message), ex);
            }

        }

        /// <summary>
        /// Deletes a resource.
        /// </summary>
        ///<param name="resourceName">The name resource.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Failed WMI method execution
        /// </exception>
        public void Delete(string resourceName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
                {
                    throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
                }
             try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("DeleteResource"))
                {
                    res.Instance.InvokeMethod("DeleteResource", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.ResourceInstances.Remove(resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.Delete", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.Delete", ex.Message), ex);
            }
        }

        ///<summary>
        /// Creates a dependency relationship between two resources.
        ///</summary>
        ///<param name="resourceName">The Resource parent.</param>
        ///<param name="resourceDependency">The resource that this resource should depend on.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// ResourceDependency not exist
        /// Failed WMI method execution
        /// </exception>
        public void AddDependency(string resourceName, string resourceDependency)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(resourceDependency))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceDependency"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            if (!_managerclass.Resources.ExistResource(resourceDependency))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceDependency));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("AddDependency"))
                {
                    inParams["Resource"] = resourceDependency;
                    res.Instance.InvokeMethod("AddDependency", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddDependency", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddDependency", ex.Message), ex);
            }
        }


        ///<summary>
        /// Removes a dependency relationship between two resources.
        ///</summary>
        ///<param name="resourceName">The Resource parent.</param>
        ///<param name="resourceRemove">The resource that this resource should depend on.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// ResourceRemove not exist
        /// Failed WMI method execution
        /// </exception>
        public void RemoveDependency(string resourceName, string resourceRemove)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(resourceRemove))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceRemove"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            if (!_managerclass.Resources.ExistResource(resourceRemove))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceRemove));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("RemoveDependency"))
                {
                    inParams["Resource"] = resourceRemove;
                    res.Instance.InvokeMethod("RemoveDependency", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveDependency", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveDependency", ex.Message), ex);
            }
        }

        ///<summary>
        /// Sets the resource dependency expression.
        ///</summary>
        ///<param name="resourceName">The resource name</param>
        ///<param name="expression">The dependency expression that this resource should depend on.</param>
        ///<remarks>
        /// This property is not supported before Windows Server 2008.
        /// </remarks>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Resource not exist
        /// Operarion System before Windows Server 2008
        /// Failed WMI method execution
        /// </exception>
        public void SetDependencies(string resourceName, string expression)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (_managerclass.OperationSystem == WindowsOperationSystem.Windows2003 || _managerclass.OperationSystem == WindowsOperationSystem.Windows2003R2)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_SystemNotSuportMethod, _managerclass.OperationSystem, "SetDependencies"));
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("SetDependencies"))
                {
                    inParams["Expression"] = expression;
                    res.Instance.InvokeMethod("SetDependencies", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.SetDependencies", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.SetDependencies", ex.Message), ex);
            }
        }

        ///<summary>
        /// Renames the resource.
        ///</summary>
        ///<param name="resourceName">The resource name to rename</param>
        ///<param name="newresourceName">The new resource name.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// NewResource exist
        /// Failed WMI method execution
        /// </exception>
        public void Rename(string resourceName, string newresourceName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(newresourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "newresourceName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            if (_managerclass.Resources.ExistResource(newresourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_AlreadyExist, "Resource", newresourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("Rename"))
                {
                    inParams["newName"] = newresourceName;
                    res.Instance.InvokeMethod("Rename", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.ResourceInstances.Remove(resourceName);
                        _managerclass.Refresh(RefreshOption.Resources,newresourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.Rename", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.Rename", ex.Message), ex);
            }
        }

        ///<summary>
        /// Adds a registry key to the list of keys being checkpointed for the resource.
        ///</summary>
        ///<param name="resourceName">The resource name</param>
        ///<param name="checkpointName">
        /// The registry key name at the root of the subtree that should be checkpointed for the resource. 
        /// This is a key name that is relative to HKEY_LOCAL_MACHINE, such as Software\Microsoft\My Application. 
        /// Do not use a leading backslash (\) in the relative path or the call will fail.
        /// </param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Failed WMI method execution
        /// </exception>
        public void AddRegistryCheckpoint(string resourceName, string checkpointName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(checkpointName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "checkpointName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("AddRegistryCheckpoint"))
                {
                    inParams["CheckpointName"] = checkpointName;
                    res.Instance.InvokeMethod("AddRegistryCheckpoint", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddRegistryCheckpoint", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddRegistryCheckpoint", ex.Message), ex);
            }
        }

        ///<summary>
        /// Removes a registry key from the list of keys being checkpointed for the resource.
        ///</summary>
        ///<param name="resourceName">The resource name</param>
        ///<param name="checkpointName">
        /// The registry key name at the root of the subtree that should be checkpointed for the resource. 
        /// This is a key name that is relative to HKEY_LOCAL_MACHINE, such as Software\Microsoft\My Application. 
        /// Do not use a leading backslash (\) in the relative path or the call will fail.
        /// </param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Failed WMI method execution
        /// </exception>
        public void RemoveRegistryCheckpoint(string resourceName, string checkpointName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(checkpointName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "checkpointName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("RemoveRegistryCheckpoint"))
                {
                    inParams["CheckpointName"] = checkpointName;
                    res.Instance.InvokeMethod("RemoveRegistryCheckpoint", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveRegistryCheckpoint", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveRegistryCheckpoint", ex.Message), ex);
            }
        }

        ///<summary>
        /// Adds an encrypted crypto key to the list of crypto keys being checkpointed for the resource.
        ///</summary>
        ///<param name="resourceName">The resource name</param>
        ///<param name="checkpointName">
        /// A pointer to a null-terminated Unicode string that specifies the cryptographic service provider (CSP) key container to be replicated. 
        /// The CSP key container must first be created with the CryptoAPI, and the keys in the container must be exportable. 
        /// The string must specify the CSP provider type, provider name, and key container name using the following syntax:
        /// Type\Name\Key
        /// Notes that the values must be separated by a backslash (\). 
        /// The provider type should specify the decimal value of the type, not the constant that represents the value. 
        /// For example, instead of "PROV_RSA_FULL", use "1". 
        /// The provider name is optional; if the provider name is omitted, the default CSP provider name associated with the specified provider type will be used.
        /// </param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Failed WMI method execution
        /// </exception>
        public void AddCryptoCheckpoint(string resourceName, string checkpointName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(checkpointName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "checkpointName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("AddCryptoCheckpoint"))
                {
                    inParams["CheckpointName"] = checkpointName;
                    res.Instance.InvokeMethod("AddCryptoCheckpoint", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddCryptoCheckpoint", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddCryptoCheckpoint", ex.Message), ex);
            }
        }

        ///<summary>
        /// Removes a crypto key from the list of keys being checkpointed for the resource.
        ///</summary>
        ///<param name="resourceName">The resource name</param>
        ///<param name="checkpointName">
        /// A pointer to a null-terminated Unicode string that specifies the cryptographic service provider (CSP) key container to be replicated. 
        /// The CSP key container must first be created with the CryptoAPI, and the keys in the container must be exportable. 
        /// The string must specify the CSP provider type, provider name, and key container name using the following syntax:
        /// Type\Name\Key
        /// Notes that the values must be separated by a backslash (\). 
        /// The provider type should specify the decimal value of the type, not the constant that represents the value. 
        /// For example, instead of "PROV_RSA_FULL", use "1". 
        /// The provider name is optional; if the provider name is omitted, the default CSP provider name associated with the specified provider type will be used.
        /// </param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Failed WMI method execution
        /// </exception>
        public void RemoveCryptoCheckpoint(string resourceName, string checkpointName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(checkpointName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "checkpointName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("RemoveCryptoCheckpoint"))
                {
                    inParams["CheckpointName"] = checkpointName;
                    res.Instance.InvokeMethod("RemoveCryptoCheckpoint", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveCryptoCheckpoint", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemoveCryptoCheckpoint", ex.Message), ex);
            }
        }
        ///<summary>
        /// Adds a possible owner (host) node to the list of possible owners for this resource.
        ///</summary>
        ///<param name="resourceName">The Resource name</param>
        ///<param name="nodeName">The Node name</param>
        /// <remarks>
        /// This method is not supported before Windows Server 2008.
        /// </remarks>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Node not exist
        /// Operarion System before Windows Server 2008
        /// Failed WMI method execution
        /// </exception>
        public void AddPossibleOwner(string resourceName, string nodeName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (_managerclass.OperationSystem == WindowsOperationSystem.Windows2003 || _managerclass.OperationSystem == WindowsOperationSystem.Windows2003R2)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_SystemNotSuportMethod, _managerclass.OperationSystem, "AddPossibleOwner"));
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(nodeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "nodeName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            if (!_managerclass.Nodes.ExistNode(nodeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Node", nodeName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("AddPossibleOwner"))
                {
                    inParams["NodeName"] = nodeName;
                    res.Instance.InvokeMethod("AddPossibleOwner", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddPossibleOwner", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.AddPossibleOwner", ex.Message), ex);
            }
        }

        ///<summary>
        /// Removes a possible owner node (host) from the list of possible owners for this resource.
        ///</summary>
        ///<param name="resourceName">The Resource name</param>
        ///<param name="nodeName">The Node name</param>
        /// <remarks>
        /// This method is not supported before Windows Server 2008.
        /// </remarks>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameters empty
        /// Resource not exist
        /// Node not exist
        /// Operarion System before Windows Server 2008
        /// Failed WMI method execution
        /// </exception>
        public void RemovePossibleOwner(string resourceName, string nodeName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (_managerclass.OperationSystem == WindowsOperationSystem.Windows2003 || _managerclass.OperationSystem == WindowsOperationSystem.Windows2003R2)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_SystemNotSuportMethod, _managerclass.OperationSystem, "RemovePossibleOwner"));
            }
            if (string.IsNullOrEmpty(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceName"));
            }
            if (string.IsNullOrEmpty(nodeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "nodeName"));
            }
            if (!_managerclass.Resources.ExistResource(resourceName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resource", resourceName));
            }
            if (!_managerclass.Nodes.ExistNode(nodeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Node", nodeName));
            }
            try
            {
                var res = _managerclass.Resources.GetResource(resourceName);
                using (var inParams = res.Instance.GetMethodParameters("RemovePossibleOwner"))
                {
                    inParams["NodeName"] = nodeName;
                    res.Instance.InvokeMethod("RemovePossibleOwner", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.Refresh(RefreshOption.Resources,resourceName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemovePossibleOwner", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Resources.RemovePossibleOwner", ex.Message), ex);
            }
        }

        #endregion

    }
}
